﻿using System;
using System.Security.Cryptography;
using System.Text;

namespace YYFUtils
{
    /// <summary>
    /// MD5加密
    /// </summary>
    public static class EncryHelper
    {
        public static string Md5By16(string value, bool tolower = true)
        {
            return Md5By16(value, Encoding.UTF8, tolower);
        }

        public static string Md5By16(string value, Encoding encoding, bool tolower = true)
        {
            return Md5(value, encoding, 4, 8, tolower);
        }

        public static string Md5By32(string value, bool tolower = true)
        {
            return Md5By32(value, Encoding.UTF8, tolower);
        }

        public static string Md5By32(string value, Encoding encoding, bool tolower = true)
        {
            return Md5(value, encoding, null, null, tolower);
        }

        private static string Md5(string value, Encoding encoding, int? startIndex, int? length, bool tolower = true)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                return string.Empty;
            }

            MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider();
            string text;
            try
            {
                byte[] array = mD5CryptoServiceProvider.ComputeHash(encoding.GetBytes(value));
                text = ((!startIndex.HasValue) ? BitConverter.ToString(array) : BitConverter.ToString(array, startIndex.GetValueOrDefault(), length.GetValueOrDefault()));
            }
            finally
            {
                mD5CryptoServiceProvider.Clear();
            }
            if (tolower)
            {
                return text.Replace("-", "").ToLower();
            }
            return text.Replace("-", "");
        }



        /// <summary>
        /// 获取MD5
        /// </summary>
        /// <param name="encypStr"></param>
        /// <returns></returns>
        public static string GetMd5(this string encypStr)
        {
            return MD5(encypStr, "GB2312");
        }

        /// <summary>
        ///  获取MD5加密字符串（支持微信MD5签名）
        /// </summary>
        /// <param name="encypStr">加密字符串</param>
        /// <param name="charset">编码 默认 GB2312</param>
        /// <param name="toLower">大小写  默认小写</param>
        /// <returns></returns>
        public static string MD5(string encypStr, string charset, bool toLower = true)
        {
            var m5 = new MD5CryptoServiceProvider();
            //创建md5对象
            byte[] inputBye;
            //使用GB2312编码方式把字符串转化为字节数组．
            try
            {
                inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
            }
            catch (Exception)
            {
                inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
            }
            var outputBye = m5.ComputeHash(inputBye);
            var retStr = BitConverter.ToString(outputBye);
            retStr = retStr.Replace("-", "").ToUpper();
            if (toLower)
            {
                retStr = retStr.ToLower();
            }
            return retStr;
        }
        /// <summary>
        ///   签名算法
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static string GetSha1(string str)
        {
            //建立SHA1对象
            SHA1 sha = new SHA1CryptoServiceProvider();
            //将mystr转换成byte[] 
            var enc = new ASCIIEncoding();
            var dataToHash = enc.GetBytes(str);
            //Hash运算
            var dataHashed = sha.ComputeHash(dataToHash);
            //将运算结果转换成string
            var hash = BitConverter.ToString(dataHashed).Replace("-", "");
            return hash;
        }

        /// <summary>
        /// 根据微信小程序平台提供的解密算法解密数据  
        /// </summary>
        /// <param name="encryptedData"></param>
        /// <param name="iv"></param>
        /// <param name="sessionKey"></param>
        /// <returns></returns>
        public static string DecryptMiniProgram(string encryptedData, string iv, string sessionKey)
        {
            //创建解密器生成工具实例  
            var aes = new AesCryptoServiceProvider
            {
                //设置解密器参数  
                Mode = CipherMode.CBC,
                BlockSize = 128,
                Padding = PaddingMode.PKCS7
            };
            //格式化待处理字符串  
            var byte_encryptedData = Convert.FromBase64String(encryptedData);
            var byte_iv = Convert.FromBase64String(iv);
            var byte_sessionKey = Convert.FromBase64String(sessionKey);

            aes.IV = byte_iv;
            aes.Key = byte_sessionKey;
            //根据设置好的数据生成解密器实例  
            using (var transform = aes.CreateDecryptor())
            {
                //解密  
                var final = transform.TransformFinalBlock(byte_encryptedData, 0, byte_encryptedData.Length);

                //获取结果  
                return Encoding.UTF8.GetString(final);
            }
        }
    }
}
